package com.my.springboot.tuling.concurrent.demo;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 多线程读取同一个文件
 * 说明：此方法未对文件分块，多个线程读取一个文件方法并不会提高读取效率，原因是线程切换会消耗资源开销
 * 优化：使用多线程可以将文件分成多个块，每个线程负责读取其中的一部分，从而并行读取整个文件，减少了读取时间
 */
public class MultiReadFiles implements Runnable{
    //定义文件读取的游标位置
    private static int now=0;
    //定义即将被读取的文件
    static File file=new File("D:\\gc2\\update.txt");
    //使用io包中的RandomAccessFile类，支持文件的随机访问
    static RandomAccessFile raf=null;
    //定义每次读取的字节数
    final static int len=256;

    private long millis;

    MultiReadFiles(long millis) throws IOException {
        this.millis = millis;
        raf=new RandomAccessFile(file, "rw");
    }
    @Override
    public void run() {
        while(true){
            try {
                //synchronized实现多线程的同步
                synchronized (raf) {
                    //将文件内容读取到b字节数组中
                    byte[] b = new byte[len];
                    //设置游标位置
                    raf.seek(now);
                    int temp=raf.read(b);
                    //如果没读取到，就结束线程
                    if(temp==-1){
                        return ;
                    }
                    //设置游标偏移量
                    now+=temp;
                    //打印文件内容
                    System.out.println(new String(b));
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally {
                long end = System.currentTimeMillis();
                System.out.println(Thread.currentThread().getName()+",结束时间：" + end);
                System.out.println(Thread.currentThread().getName()+",耗时：" + (end - millis));
            }
        }

    }
}

class MultiReadFilesTest{
    public static void main(String[] args) throws IOException {
        long start = System.currentTimeMillis();//33
        System.out.println(Thread.currentThread().getName()+"，开始时间：" + start);
        MultiReadFiles concurrentReadFiles = new MultiReadFiles(start);
        new Thread(concurrentReadFiles,"a").start();
        //new Thread(concurrentReadFiles,"b").start();
        //new Thread(concurrentReadFiles,"c").start();

    }
}